/**
 * Assignment Two
 * Analyze the code presented in the IO program.
 * Edit the code to run for lowercase letters “a-e”.
 *
 * @author: Unknown
 *  Editor: John Thomason
 *  Course: CS222 Java II
 * Seminar: 3
 *  Assign: 2
 */
import java.io.*;

public class IO {

    public static void main(String[] Jim) throws IOException {

        //Declaring variables
        BufferedReader dataIn = new BufferedReader(
                                new InputStreamReader(System.in));
        int num = 0;
        char begin   = 'a';     //Beginning character
        char end     = 'e';     //Ending character
        String decNum;
        String binNum;
        boolean done = false;

        //Main Loop to get and validate user input
        do {

            try { //to get valid user input

                displayMenu(begin,end);
                decNum = dataIn.readLine();
                num = Integer.parseInt(decNum);
                validate(num,begin,end);
                done = true;

            }//try

            catch(NumberFormatException e) { //User made a Boo Boo!

                prt("\nYour response was not a valid number.\n");
                prt("Please reenter using the allowable numeric values.\n");

            }//catch()

        } while(!done);//do/while loop

        //Convert the decimal number to a binary string
        binNum = getBinary(num);
        //Display Output
        prt(String.format("\nThe binary equivalent of %d is %s\n\n",
                             num, binNum));

    } //end main


    //PRIVATE SUPPORTING METHODS

    /**
     * Display the menu to prompt the user for input
     *
     * @param begin The first menu item
     * @param end   The last menu item
     */
    private static void displayMenu(char begin, char end){

        //Prompt the user for input
        prt("\nEnter the decimal number for the ascii letter\n");

        //Display integer values and characters from begin to end
        for( char c = begin; c <= end; c++ ){
            prt(String.format("\t%3d) %c\n", (int)c, c));
        }//for()

        //Display final prompt
        prt("Enter Number: ");

    }//displayMenu()


    /**
     * Validate the user input
     *
     * @param num   The user entered value
     * @param begin The beginning item in the acceptable range
     * @param end   The ending item in the acceptable range
     * @throws java.lang.NumberFormatException
     */
    private static void validate(int num, char begin, char end)
    throws NumberFormatException {

        //Validate the number entered is within character range
        if( num < (int)begin || num > (int)end ){

            prt(String.format("\nThe number must be between %d and %d.",
                                 (int)begin, (int)end));
            throw new NumberFormatException();

        }// end if

    }//validate()


    /**
     * Converts a decimal value less than or equal to 256 to
     * a 8 character string representing it's binary equivalent.
     *
     * @param findBin   The decimal value to convert
     * @return          A string representing the binary value
     */
    private static String getBinary(int findBin){

        //StringBuilder used because it's mutable
        StringBuilder theBinary = new StringBuilder();

        //Build the binary string in reverse
        while(findBin > 0){
            theBinary.append(findBin % 2);
            findBin /= 2;
        }//while()

        //Pad to 8 bit length
        while(theBinary.length() < 8){ theBinary.append("0"); }

        //reverse the StringBuilder array and return as a String
        return theBinary.reverse().toString();

    }// end getBinary


    /**
     * Display a formatted message string
     *
     * @param msg   The formatted message string
     */
    private static void prt(String msg){
        System.out.print(msg);
    }//prt

} //End IO class